/*
 * The contents of this web application are subject to the Mozilla Public License Version 
 * 1.1 (the "License"); you may not use this web application except in compliance with 
 * the License. You may obtain a copy of the License at http://www.mozilla.org/MPL/.
 * 
 * Software distributed under the License is distributed on an "AS IS" basis, 
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License 
 * for the specific language governing rights and limitations under the License.
 * 
 * The Original Code is owned by and the Initial Developer of the Original Code is 
 * Composite A/S (Danish business reg.no. 21744409). All Rights Reserved
 * 
 * Section 11 of the License is EXPRESSLY amended to include a provision stating 
 * that any dispute, including but not limited to disputes related to the enforcement 
 * of the License, to which Composite A/S as owner of the Original Code, as Initial 
 * Developer or in any other role, becomes a part to shall be governed by Danish law 
 * and be initiated before the Copenhagen City Court ("K�benhavns Byret")            
 */

using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Workflow.Activities;
using Composite.C1Console.Elements.ElementProviderHelpers.AssociatedDataElementProviderHelper;
using Composite.Data;
using Composite.Data.DynamicTypes;
using Composite.Data.GeneratedTypes;
using Composite.Data.ProcessControlled;
using Composite.Core.Types;
using Composite.C1Console.Workflow;
using Composite.C1Console.Users;


namespace Composite.Plugins.Elements.ElementProviders.GeneratedDataTypesElementProvider
{
    [EntityTokenLock()]
    [AllowPersistingWorkflow(WorkflowPersistingType.Idle)]
    public sealed partial class EnableTypeLocalizationWorkflow : Composite.C1Console.Workflow.Activities.FormsWorkflow
    {
        public EnableTypeLocalizationWorkflow()
        {
            InitializeComponent();
        }



        private DataTypeDescriptor GetDataTypeDescriptor()
        {
            Type type;

            if (this.EntityToken is AssociatedDataElementProviderHelperEntityToken)
            {
                var castedEntityToken = this.EntityToken as AssociatedDataElementProviderHelperEntityToken;

                type = TypeManager.GetType(castedEntityToken.Payload);
            }
            else
            {
                var entityToken = (GeneratedDataTypesElementProviderTypeEntityToken)this.EntityToken;
                type = TypeManager.GetType(entityToken.SerializedTypeName);
            }

            Guid guid = type.GetImmutableTypeId();

            return DataMetaDataFacade.GetDataTypeDescriptor(guid);
        }



        private void LocalesExists(object sender, ConditionalEventArgs e)
        {
            e.Result = DataLocalizationFacade.ActiveLocalizationCultures.Any();
        }



        private void step1CodeActivity_Initialize_ExecuteCode(object sender, EventArgs e)
        {
            var culturesDictionary = DataLocalizationFacade.ActiveLocalizationCultures.ToDictionary(f => f.Name, DataLocalizationFacade.GetCultureTitle);

            this.UpdateBinding("CultureName", (UserSettings.ForeignLocaleCultureInfo ?? UserSettings.ActiveLocaleCultureInfo).Name);
            this.UpdateBinding("CultureNameList", culturesDictionary);
        }



        private void finalizeCodeActivity_Finalize_ExecuteCode(object sender, EventArgs e)
        {
            DataTypeDescriptor dataTypeDescriptor = GetDataTypeDescriptor();

            // Making changes to type
            DataTypeDescriptor newDataTypeDescriptor = dataTypeDescriptor.Clone();
            newDataTypeDescriptor.AddSuperInterface(typeof(ILocalizedControlled));

            List<CultureInfo> localesToCopyTo = new List<CultureInfo>();
            if (ThereAreReferencesInLocalizedData())
            {
                localesToCopyTo.AddRange(DataLocalizationFacade.ActiveLocalizationCultures);
            }
            else
            {
                string cultureName = this.GetBinding<string>("CultureName");
                localesToCopyTo.Add(CultureInfo.CreateSpecificCulture(cultureName));
            }

            var updateDataTypeDescriptor = new UpdateDataTypeDescriptor(dataTypeDescriptor, newDataTypeDescriptor, false)
            {
                LocalesToCopyTo = localesToCopyTo
            };

            GeneratedTypesFacade.UpdateType(updateDataTypeDescriptor);

            this.CloseCurrentView();
            this.CollapseAndRefresh();
        }

        private bool ThereAreReferencesInLocalizedData()
        {
            if (DataLocalizationFacade.ActiveLocalizationCultures.Count() == 1)
            {
                return false;
            }

            Type type = GetDataTypeDescriptor().GetInterfaceType();

            return type.GetRefereeTypes().Any(DataLocalizationFacade.IsLocalized);
        }

        private void ThereAreReferencesInLocalizedData(object sender, ConditionalEventArgs e)
        {
            e.Result = ThereAreReferencesInLocalizedData();
        }
    }
}
